/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/system/io
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEFileInStreamI.h
// Author:		Gianluca Belardelli
// Date:		07/10/2014
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEFILEINSTREAMI_H_
#define _AEFILEINSTREAMI_H_

class AEFileInStreamI : public AEBaseFileStreamI
{
// Members
protected:
	char		*m_lpMetaData;
	char		*m_lpInitialSearchPath;
	AEUINT32	m_uiLookupHash;
	AEBOOL32	m_bEOF;

	AEDateTime	m_dtTimeStamp;

// Methods
public:
	/// \brief
	///   Initializes this file stream, optionally passing the file system that created this stream.
	AEFileInStreamI( AEFileSystemI *lpFileSystem = 0L );

	/// \brief
	///   Destructor
	virtual ~AEFileInStreamI( void );

	/// \brief
	///   Reads up to iLen number of bytes to pBuffer. Returns the exact number of bytes that was read (may be smaller than iLen).
	/// 
	/// \param pBuffer
	///   The destination buffer.
	/// 
	/// \param iLen
	///   Number of bytes to read.
	/// 
	/// \return
	///   size_t iRead : Number of actual bytes read.
	virtual AEUINT32 Read( void *lpBuffer, AEINT32 nLen ) = 0;

	/// \brief
	///   Read function that performs endianness conversion on the read buffer.
	/// 
	/// This version of the read function calls the virtual Read function and performs the conversion
	/// on the read block.
	/// 
	/// The expected format is passed in the format string.
	/// 
	/// Each character in the format string represents a data type: i=int, s=short, c=char, f=float, q=quad word (8bytes)
	/// For full documentation of the format string see the EndianSwitchWorker() documentation.
	/// 
	/// \param pBuffer
	///   The destination buffer.
	/// 
	/// \param iLen
	///   Length of the buffer in bytes, must be large enough to hold the data that the format string specifies (ie. if "f" is used to read a float, the buffer must be at least 4 bytes large).
	/// 
	/// \param pFormat
	///   Format specification, see EndianSwitchWorker() for more details.
	/// 
	/// \param iRepetitions
	///   Number of repetitions of the format string.
	/// 
	/// \return
	///   size_t iRead : Number of actual bytes read.
	/// 
	/// \example
	///   Reads two integers into a structure:
	///   \code
	///   pFile->Read(&header, sizeof(header),"ii", 1);
	///   \endcode
	//VBASE_IMPEXP size_t Read(void* pBuffer, int iLen, const char *pFormat, unsigned int iRepetitions = 1);


	/// \brief
	///   Sets the byte position where to read/write the file. This function will be removed in the future.
	/// 
	/// \param iPos
	///   Position relative to base position (iMode)
	/// 
	/// \param iMode
	///   Base position. Must be VFS_SETPOS_SET, VFS_SETPOS_CURRENT or VFS_SETPOS_END (from the VFilePositionMode enum).
	virtual AEBOOL32 SetPos( AEINT64 nPos, AEFileSeek eMode ) = 0;

	/// \brief
	///   Returns the current file position.
	virtual AEINT64 GetPos( void ) = 0;

	/// \brief
	///   Returns the size of the file in bytes.
	virtual AEINT64 GetSize( void ) = 0;

	/// \brief
	///   Indicates whether the end of file has been reached.
	AE_FORCEINLINE AEBOOL32 IsEOF( void );

	/// \brief
	///  Sets the modification date of the file the stream points to.
	 void SetTimeStamp( const AEDateTime &dtTimeStamp );

	/// \brief
	///  Returns the modification date of the file the stream points to.
	 AEBOOL32 GetTimeStamp( AEDateTime &dtResult ) const;

	/// \brief
	///   Sets the search path in which the asset for this stream was first successfully looked up.
	/// \param szSearchPath
	///   The search path to set.
	 void SetInitialSearchPath( const char *lpSearchPath );

	/// \brief
	///   Gets the search path in which the asset for this stream was first
	///   successfully looked up. If the stream was not opened using a relative path,
	///   this function returns an empty string, as no look-up has taken place.
	/// \return
	///   The initial search path, or \c NULL if this stream was not opened without look-up.
	AE_FORCEINLINE const char *GetInitialSearchPath( void ) const;

	/// \brief
	///   Sets the metadata string to go with this stream.
	/// \param szMetadata
	///   The metadata string. Can be NULL.
	 void SetMetadata( const char *lpMetadata );

	/// \brief
	///   Returns the metadata string set for this stream.
	/// \return
	///   The metadata set for this stream. May be empty, but never \c NULL.
	const char *GetMetadata( void ) const;

	/// \brief
	///   Sets the hash of the asset lookup entry that identified the underlying file in the relevant asset lookup table.
	/// \param uiHash
	///   the hash value to set
	void SetLookupHash( AEUINT32 uiHash );

	/// \brief
	///   Returns the hash of the asset lookup entry that identified the underlying file in the relevant asset lookup table.
	/// \return
	///   the hash value (0 if not explicitly set)
	AEUINT32 GetLookupHash( void ) const;

	///
	/// @name Read Operators
	/// @{
	///
	/*
	/// \brief
	///   Reads a char from the stream
	AE_FORCEINLINE AEFileInStreamI &operator>>( char &ch );

	/// \brief
	///   Reads a signed char from the stream
	AE_FORCEINLINE AEFileInStreamI &operator>>( signed char &ch );

	/// \brief
	///   Reads a bool from the stream
	AE_FORCEINLINE AEFileInStreamI &operator>>( bool &b );

	/// \brief
	///   Reads a BYTE from the stream
	 AEFileInStreamI &operator>>( AEUINT8 &uiByte );

	/// \brief
	///   Reads a WORD from the stream
	 AEFileInStreamI &operator>>( AEUINT16 &uiWord );

	/// \brief
	///   Reads a DWORD from the stream
	 AEFileInStreamI &operator>>( AEUINT32 &uiDword );

	/// \brief
	///   Reads an __int64 from the stream
	 AEFileInStreamI &operator>>( AEUINT64 &uiQWord );

	/// \brief
	///   Reads a VFloat16 from the stream
	 AEFileInStreamI &operator>>( AEFLOAT32 &fFloat );

	/// \brief
	///   Reads a double from the stream
	 AEFileInStreamI &operator>>( AEDOUBLE64 &dDouble );

	/// \brief
	///   Reads a double from the stream
	 AEFileInStreamI &operator>>( AEBOOL32 &bBool );

	/// \brief
	///   Reads a double from the stream
	 AEFileInStreamI &operator>>( bool &bBool );

	/// \brief
	///   Reads a short from the stream
	AE_FORCEINLINE AEFileInStreamI &operator>>( AEINT16 &nShort );

	/// \brief
	///   Reads an int from the stream
	AE_FORCEINLINE AEFileInStreamI &operator>>( AEINT32 &nInt );

	/// \brief
	///   Reads an unsigned int from the stream
	AE_FORCEINLINE AEFileInStreamI &operator>>( AEINT8 &nChar );
	*/
	///
	/// @}
	///
};

#endif // _AEFILEINSTREAM_H_
